home *** CD-ROM | disk | FTP | other *** search
/ Atari Forever 1 / Atari Forever 1 / Atari Forever 1.iso / pd_thema / diskmoni / filemon / filemon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-21  |  23.6 KB  |  859 lines

  1.  
  2. /*
  3.         FileMon V1.0    (C) 1989 C.Peppermüller
  4.                 P u b l i c    D o m a i n
  5.         Achtung! Bei vielen Änderungen dieses Quelltextes
  6.         können unerwünschte Seiteneffekte auftreten!
  7.  
  8.         geschrieben mit Turbo-C V1.0
  9. */
  10.  
  11. /* Libraries ... */
  12.  
  13. #include <stdio.h>
  14. #include <ext.h>
  15. #include <tos.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. #define putstr(a) fputs(a,stdout)
  20.         /* Stringausgabe ohne Zeilenvorschub */
  21.  
  22. /*    Für schnelle Änderungen hier alle wichtigen Texte, bis auf die
  23.     Prozessorbefehle, die so bleiben sollten, wie sie sind.            */
  24.  
  25. #define txt1 "Ein Parameter langt."
  26. #define txt2 "Auf Wiedersehen!\x1B""f\x1Bw"
  27. #define txt3 "Tschüß!\n\x1B""f\x1Bw"
  28. #define txt4 "\x1B""E\x1B""e\x1Bv\n" \
  29.          "************************************************\n" \
  30.          "*                                              *\n" \
  31.          "*  FILEMON V1.0 - der ultimative File-Manager  *\n" \
  32.          "*                 zum Patchen + Textsuchen     *\n" \
  33.          "*      (C) 1989 Christian Peppermüller         *\n" \
  34.          "*        P u b l i c    D o m a i n            *\n" \
  35.          "*                                              *\n" \
  36.          "************************************************"
  37. #define txt5  "?DEFGHLOQSTWX"
  38. #define txt6  "\nBitte den Filenamem: "
  39. #define txt7  "Von Kommandozeile: "
  40. #define txt8  "Nanu - File nicht gefunden !"
  41. #define txt9  "Oh - Kein Speicher."
  42. #define txt10 "Nanu - kann File nicht lesen !"
  43. #define txt11 "Filelänge: $%6lX\n"
  44. #define txt12 "\x1b""E\n" \
  45.     "***************************************\n"        \
  46.     "*          Hilfe - FileMon            *\n"        \
  47.     "***************************************\n\n"    \
  48.     "?                Diese Hilfe.\n"                \
  49.     "X,T              Wechselt zu Modus HEX (X) oder TEXT (T).\n" \
  50.     "D{a {b}}         Dump von a bis b; Text mit of/ox.\n"        \
  51.     "Wfilename        Sichert das (veränderte) File.\n"            \
  52.     "Oof              Setzt Offset für Text bei D und C.\n"        \
  53.     "Eox              Setzt EOR-Byte für Text bei D und C.\n"    \
  54.     "Sa {b}           Ändert Text/Bytes von a bis b; im\n"        \
  55.     "                 Modus T: of/ox. Extra-Byte absolut.\n"    \
  56.     "F{a b {o1 o2}}   Sucht Text/Bytes von a bis b mit Offset\n"\
  57.     "  + text/bytes   o1 bis o2. Text mit ox !\n"                \
  58.     "G...             wie F, aber mit EOR-Byte von o1 bis o2.\n"\
  59.     "Ha b             liefert a+b  a-b (Hex-Arithmetik).\n"        \
  60.     "L{a {b}}         Disassembliert von a bis b.\n"            \
  61.     " a,b:            HEX-Langworte bzgl Filebeginn.\n"            \
  62.     " of,ox,o1,o2:    HEX-Bytes.   {}:Optional.\n"                \
  63.     " filename,text:  ASCII-Text.  bytes: bis zu 78 HEX-Bytes.\n"\
  64.     " Kommandozeile:  Kommandos, Modus (X/T), of , ox .\n"
  65. #define txt13 "Offset geändert."
  66. #define txt14 "Eor-Byte geändert."
  67. #define txt15 "Nanu - Kann File nicht zum Schreiben öffnen !"
  68. #define txt16 "Achtung - File gekürzt (Disk voll?) !"
  69. #define txt17 "Nanu - Kann File nicht schließen !"
  70. #define txt18 "%s in $%lX Bytes abgespeichert.\n"
  71. #define txt19 "mehrzeilige Texteingabe. Ende durch Leerzeile."
  72. #define txt20 "Nun noch das absolute HEX-Endbyte (<RETURN> keins):"
  73. #define txt21 "Eingabe: Byte1 <RETURN>,.., Ende: Leerzeile."
  74. #define txt22 "Suche Text: "
  75. #define txt23 "Suche: Byte <RETURN>,..; Suche starten mit Leerzeile."
  76. #define txt24 "\nBytes/Text gefunden "
  77. #define txt25 "\nAbbruch "
  78. #define txt26 "bei $%6lX mit Offset $%2X .\n"
  79. #define txt27 "bei %6lX mit EOR-Byte $%2X .\n"
  80. #define unbekannt "unknown"
  81.  
  82. /* alles ... */
  83.  
  84. /* Funktions-Prototypen ( ANSI-C... ) */
  85.  
  86. int                filopen        (long a,int b,char *c);
  87. char            menu        (void);
  88. void            init_all    (void);
  89. void            dump        (void);
  90. void            save        (void);
  91. void            change        (void);
  92. void            search        (char a);
  93. void            help        (void);
  94. void            offset        (void);
  95. void            xorset        (void);
  96. void            hex            (void);
  97. void            founds        (long a,int b,int c,char d);
  98. int                ausw        (char *a,int b,long *c,long d);
  99. void            disassemble    (void);
  100. void            disass        (void);
  101. unsigned int    getword        (void);
  102. char            *branch        (unsigned int a,int b);
  103. char            *getlen        (int a);
  104. void            addr        (char *a,unsigned int b,unsigned int c);
  105. void            movemreg    (char *a,int b);
  106. unsigned int    qnum        (unsigned int a);
  107.  
  108. /* Ein paar Variablen */
  109.  
  110. unsigned char     *filstart,*physfilbuf,*curbyte,*cmdlin,*cmdlist;
  111. char             bufstr[70],dat1[30],dat2[30],opt;
  112. long             flen,physflen,an,en,PCcount,h1,h2;
  113. unsigned int    cmdw,art,adr1,reg1,adr2,reg2;
  114. int             ofs,xorb,cmdlen;
  115.  
  116. /* Hier das Hauptprogramm */
  117.  
  118. int main(int argc,char *argv[])
  119. {
  120.     char c;
  121.     init_all();
  122.     if (argc>2) puts(txt1);
  123.     do {
  124.         h1=filopen(h1,argc,argv[1]);
  125.     } while ((h1>0) && (h1<4));
  126.     if (h1)
  127.     {    puts(txt2);
  128.         return (-1);    }
  129.     do{
  130.         rewind (stdin); c=menu();
  131.         switch(c)
  132.         {    case'D': dump();          break;
  133.             case'W': save();          break;
  134.             case'S': change();        break;
  135.             case'L': disassemble();    break;
  136.             case'G':
  137.             case'F': search(c);        break;
  138.             case'X':
  139.             case'T': opt=c;           break;
  140.             case'?': help();        break;
  141.             case'H': hex();            break;
  142.             case'O': offset();        break;
  143.             case'E': xorset();        }
  144.     } while (c!='Q');
  145.     puts(txt3);
  146.     free(physfilbuf);
  147.     return(0);
  148. }
  149. void init_all()
  150. {    
  151.     puts(txt4);
  152.     opt='X'; h1=an=en=ofs=xorb=0; rewind(stdin);
  153.     cmdlist=txt5;
  154.     return;
  155. }
  156.  
  157. /** filopen() liest zu bearbeitendes File ganz ein. **/
  158.  
  159. int filopen(long mode,int compar,char argum[])
  160. {
  161.     int handle;
  162.     long tst;
  163.     if (mode || (compar<2))
  164.     {    putstr (txt6); gets (bufstr);    }
  165.     else
  166.     {    strcpy (bufstr,argum);
  167.         putstr (txt7); puts (bufstr);    }
  168.     if ((handle=Fopen (bufstr,0))<0)
  169.     {    puts (txt8); return(++mode);    }
  170.     physflen=Fseek (0L,handle,2);
  171.     Fseek (0L,handle,0);
  172.     physfilbuf=malloc (physflen+70L);
  173.     if (physfilbuf==NULL)
  174.     {    Fclose(handle); puts(txt9); return (-1);    }
  175.     tst=Fread (handle,physflen,physfilbuf);
  176.     Fclose (handle);
  177.     if ((physflen<=0) || (tst<physflen))
  178.     {    puts (txt10);
  179.         free (physfilbuf);    return (++mode);    }
  180.     printf (txt11,physflen);
  181.     filstart=physfilbuf; flen=physflen;
  182.     if ((*filstart==0x60) && (*(filstart+1L)==0x1A))
  183.     {    flen-=0x1C; filstart+=0x1CL;    }
  184.     return(0);
  185. }
  186.  
  187. char menu()
  188. {
  189.     char cc;
  190.     do {
  191.         printf ("%s *%c*%02X*%02X* >",cmdlist,opt,ofs,xorb);
  192.         rewind(stdin); gets(bufstr);
  193.         cc=bufstr[0]; if (cc>'Z') cc-=32;
  194.     } while (strchr(cmdlist,cc)==NULL);
  195.     cmdlin=&(bufstr[1]);
  196.     return (cc);
  197. }
  198.  
  199. void help()
  200. {    puts(txt12);
  201.     return;
  202. }
  203. void offset()
  204. {
  205.     if (cmdlin[0]==0) return;
  206.     sscanf (cmdlin,"%x",&ofs);
  207.     puts(txt13);
  208.     return;
  209. }
  210. void xorset()
  211. {
  212.     if (cmdlin[0]==0) return;
  213.     sscanf (cmdlin,"%x",&xorb);
  214.     puts(txt14);
  215.     return;
  216. }
  217. void dump()
  218. {
  219.     long i,j,stp;
  220.     int byt,brk;
  221.     unsigned char *fzchn,dmp[17],c;
  222.     dmp[0]=' '; dmp[17]=brk=0; en=0L;
  223.     if    (cmdlin[0])
  224.     {    sscanf(cmdlin,"%lX %lX",&an,&en); if (an<0) an=0;    }
  225.     if (en==0L)        en=an+((opt=='T')? 0x3FFL: 0xFFL);
  226.     if (en>flen)    en=flen;
  227.     stp=(opt=='T')? 64: 16;
  228.     i=an;
  229.     if (an>flen)    an=flen;
  230.     while (i<=en)
  231.     {    fzchn=&(filstart[i]);
  232.         printf ("%6lX : ",i);
  233.         for (j=i;j++<i+stp;)
  234.         {    byt=*(fzchn++);
  235.             if (j>flen) byt=0;
  236.             c=(((byt+ofs)&0xFF)^xorb);
  237.             if (c<' ')    c='.';
  238.             switch (opt)
  239.             {    case'T':    putchar(c);    break;
  240.                 case'X':    dmp[j-i]=c;    printf (" %02X",byt);    }
  241.             if (kbhit())
  242.                 if ((getch()&0xFF)==27)    brk=1;    }
  243.         an=i;
  244.         if (brk)    {    putchar('\n'); return;    }
  245.         if (opt=='T')    putchar('\n');
  246.           else    {    putstr("   "); puts(dmp);    }
  247.         i+=stp;    }
  248.     an=i;
  249.     return;
  250. }
  251. void save()
  252. {
  253.     int handle;
  254.     long tst;
  255.     if (cmdlin[0]>31)    handle=Fcreate(cmdlin,0);
  256.         else            handle=-1;
  257.     if (handle<0)
  258.     {    puts(txt15);
  259.         return;    }
  260.     tst=Fwrite (handle,physflen,physfilbuf);
  261.     if (tst<flen)
  262.         puts(txt16);
  263.     if (Fclose(handle)<0)
  264.         puts(txt17);
  265.      else printf(txt18,cmdlin,tst);
  266.     return;
  267. }
  268. void change()
  269. {
  270.     long an,en,i;
  271.     int  fl;
  272.     char text[200]; an=0L; en=flen;
  273.     sscanf(cmdlin,"%lX %lX",&an,&en);
  274.     switch(opt)
  275.     {    case'T':    puts(txt19);
  276.                     i=an;
  277.                     do {    rewind(stdin);
  278.                             printf("%6lX: > ",i);
  279.                             gets (text);
  280.                     } while (ausw(text,ofs,&i,en));
  281.                     puts(txt20);
  282.                     gets(bufstr); fl=0x300;
  283.                     sscanf(bufstr,"%x",&fl);
  284.                     if (fl<0x100)
  285.                         *(filstart+i)=fl;
  286.                     return;
  287.         case'X':    puts(txt21);
  288.                     i=an;
  289.                     while (i<=en)
  290.                     {    rewind(stdin);
  291.                         printf("%6lX: %02X > ",i,*(filstart+i));
  292.                         gets (text);
  293.                         if (text[0]==0)    break;
  294.                         sscanf(text,"%x",&fl);
  295.                         *(filstart+(i++))=fl;        }    }
  296.     return;
  297. }
  298. int ausw(char str[],int ofs,long *i,long en)
  299. {
  300.     int j;
  301.     unsigned char *zchn,z;
  302.     if (str[0]==0)    return (0);
  303.     zchn=filstart+(*i);j=0;
  304.     while (((*i)++<en-1) && ((z=str[j++])!=0))
  305.         *(zchn++)=(((z-ofs)&0xFF)^xorb);
  306.     (*i)--;
  307.     return(1);
  308. }
  309. void hex()
  310. {    long a,b;
  311.     if (cmdlin[0]==0) return;
  312.     sscanf(cmdlin,"%lX %lX",&a,&b);
  313.     printf("%lX  %lX\n",a+b,a-b);
  314.     return;
  315. }
  316. void search(char w)
  317. {
  318.     long an,en,i;
  319.     int ofs1,ofs2,curofs,lng,k,f,xorbs;
  320.     char *fzchn,*fzn,c,name[80],srch[80];
  321.     ofs1=ofs2=((opt=='X')? 0: ofs); an=0; en=flen;
  322.     xorbs=((opt=='T')? xorb: 0);
  323.     sscanf(cmdlin,"%lX %lX %x %x",&an,&en,&ofs1,&ofs2);
  324.     lng=0;
  325.     switch(opt)
  326.     {    case'T':    putstr(txt22);
  327.                     gets(name);
  328.                     lng=strlen(name);
  329.                     break;
  330.         case'X':    puts(txt23);
  331.                     do {    gets(bufstr);
  332.                             if (bufstr[0]==0)    break;
  333.                             sscanf (bufstr,"%x",&f);
  334.                             name[lng++]=(f&0xFF);
  335.                     } while (lng<79);
  336.                     name[lng]=0;    }
  337.     if (an<0)        an=0;
  338.     if (en>flen)    en=flen;
  339.     if (ofs1<0)        ofs1=0;
  340.     if (ofs1>255)    ofs1=255;
  341.     if (ofs2>255)    ofs2=255;
  342.     if (ofs2<0)        ofs2=0;
  343.     curofs=ofs1;
  344.     while (curofs<=ofs2)
  345.     {    for (k=0;k<=lng;)
  346.         {    if (w=='F') srch[k++]=(((name[k]-curofs)&0xFF)^xorbs);
  347.             else srch[k++]=(((name[k]-ofs)&0xFF)^curofs);    }
  348.         c=srch[0];
  349.         putchar('*');
  350.         i=an-1L;
  351.         fzchn=filstart+i;
  352.         while (i++<en)
  353.         {    if (*(++fzchn)==c)
  354.             {    k=0; f=1; fzn=fzchn;
  355.                 while ((++k<lng) && (f!=0))
  356.                 {    if (*(++fzn)!=srch[k]) f=0;
  357.                 }
  358.                 if (f)    founds(i,curofs,1,w);
  359.                 if (kbhit())
  360.                     if (getch()==27)
  361.                     {    founds(i,curofs,0,w);
  362.                         i=en+1; curofs=ofs2+1;    }    }    }
  363.         if (kbhit())
  364.             if ((getch()==27))
  365.             {    if (curofs<=ofs2) founds(i,curofs,0,w);
  366.                 i=en; curofs=ofs2+1;    }
  367.         curofs++;    }
  368.     puts("\n");
  369.     return;
  370. }
  371. void founds(long j,int cofs,int flg,char w)
  372. {
  373.     if (flg==1)        putstr(txt24);
  374.         else        putstr(txt25);
  375.     if (w=='F') printf(txt26,j,cofs);
  376.     else printf(txt27,j,cofs);
  377.     return;
  378. }
  379. void disassemble(void)
  380. {
  381.     en=0L;
  382.     if (cmdlin[0]) sscanf(cmdlin,"%lX %lX",&an,&en);
  383.     if (en==0L) en=an+32L;
  384.     if (an<0L)        an=0L;
  385.     if (en>flen)    en=flen;
  386.     PCcount=an; curbyte=filstart+an;
  387.     while (PCcount<en)
  388.     {    printf("%06lX: ",PCcount);
  389.         disass();
  390.         putchar('\n');
  391.         an=PCcount;
  392.         if (kbhit())
  393.             if (getch()==27) en=PCcount;        }
  394.     return;
  395. }
  396. void disass()
  397. {
  398.     char *dummy,*nokn;
  399.     cmdw=getword();
  400.     nokn=unbekannt;
  401.     dummy=bufstr;
  402.     art=(cmdw&0xF000)>>12;
  403.     reg2=(cmdw&0x0E00)>>9;
  404.     adr2=(cmdw&0x01C0)>>6;
  405.     adr1=(cmdw&0x0038)>>3;
  406.     reg1=cmdw&0x0007;
  407.     cmdlen=0; dat1[0]=0; dat2[0]=0;
  408.     dummy[0]=0;
  409.     switch(art)
  410.     {    case 0xF: dummy="line_f";
  411.             sprintf(dat1,"$%03X",cmdw&0xFFF); break;
  412.         case 0xA: dummy="line_a";
  413.             sprintf(dat1,"$%03X",cmdw&0xFFF); break;
  414.         case 0x6: dummy[0]='b';
  415.             strcpy(&dummy[1],branch(cmdw,3));
  416.             if ((h2=(cmdw&0xFF))==0) 
  417.             {    strcat(dummy,".w");
  418.                 h2=getword();
  419.                 h1=PCcount-2+((h2>0x7FFF)? -(0x10000-h2): h2);    }
  420.             else
  421.             {    strcat(dummy,".s");
  422.                 h1=PCcount+((h2>0x7F)? -(0x100-h2): h2);    }
  423.             sprintf(dat1,"$%06lX (rel)",h1); break;
  424.         case 0x1:
  425.             dummy="move.b"; cmdlen=1;
  426.             addr(dat1,adr1,reg1);
  427.             addr(dat2,adr2,reg2);
  428.             break;
  429.         case 0x2:
  430.             dummy="move.l"; cmdlen=4;
  431.             addr(dat1,adr1,reg1);
  432.             addr(dat2,adr2,reg2);
  433.             break;
  434.         case 0x3:
  435.             dummy="move.w"; cmdlen=2;
  436.             addr(dat1,adr1,reg1);
  437.             addr(dat2,adr2,reg2);
  438.             break;
  439.         case 0x0:
  440.             if ((cmdw&0x0100)==0)
  441.             {    if ((reg2!=4) && (reg2!=7))
  442.                 {    switch (reg2)
  443.                     {    case 0x0: strcpy(dummy,"ori"); break;
  444.                         case 0x1: strcpy(dummy,"andi");break;
  445.                         case 0x2: strcpy(dummy,"subi");break;
  446.                         case 0x3: strcpy(dummy,"addi");break;
  447.                         case 0x5: strcpy(dummy,"eori");break;
  448.                         case 0x6: strcpy(dummy,"cmpi");    }
  449.                     strcat(dummy,getlen(adr2&0x3));
  450.                     addr(dat1,0x7,0x4);
  451.                     if ((adr1==0x7) && (reg1==0x4))
  452.                     {    if (cmdlen==1) strcpy(dat2,"ccr");
  453.                             else    strcpy(dat2,"sr");
  454.                     } else    addr(dat2,adr1,reg1); break;    }
  455.                 if (reg2==7)    break;    }
  456.             if ((adr1==0x1) && (cmdw&0x100)) /* Movep */
  457.             {    strcpy(dummy,"movep.w"); cmdlen=2;
  458.                 if (cmdw&0x0040)
  459.                 {    cmdlen=4; dummy[6]='l';    }
  460.                 if (cmdw&0x0080)
  461.                 {    addr(dat1,0,reg2);addr(dat2,5,reg1);    }
  462.                     else
  463.                 {    addr(dat2,0,reg2);addr(dat1,5,reg1);    }
  464.                 break;    }
  465.             switch(adr2)
  466.             {    case 0x4:    dummy="btst"; break;
  467.                 case 0x7:    dummy="bset"; break;
  468.                 case 0x6:    dummy="bclr"; break;
  469.                 case 0x5:    dummy="bchg"; break;
  470.                 default:    dummy="";    }
  471.             if (dummy[0])
  472.             {    addr(dat1,0,reg2); cmdlen=1;
  473.                 addr(dat2,adr1,reg1);    break;    }
  474.             if ((cmdw&0x0F00)!=0x800)    break;
  475.             switch(adr2)
  476.             {    case 0x0:    dummy="btst"; break;
  477.                 case 0x1:    dummy="bchg"; break;
  478.                 case 0x2:    dummy="bclr"; break;
  479.                 case 0x3:    dummy="bset";    }
  480.             cmdlen=1; addr(dat1,0x7,0x4);
  481.             addr(dat2,adr1,reg1); break;
  482.         case 0x4:
  483.             if (adr2==0x7)
  484.             {    dummy="lea"; cmdlen=4; addr(dat2,0x1,reg2);
  485.                 addr(dat1,adr1,reg1);    break;    }
  486.             if (adr2==0x6)
  487.             {    dummy="chk"; cmdlen=2; addr(dat2,0x0,reg2);
  488.                 addr(dat1,adr1,reg1);    break;    }
  489.             if ((adr2<3) && (reg2<4))
  490.             {    switch(reg2)
  491.                 {    case 0x0:    strcpy(dummy,"negx"); break;
  492.                     case 0x1:    strcpy(dummy,"clr");  break;
  493.                     case 0x2:    strcpy(dummy,"neg");  break;
  494.                     case 0x3:    strcpy(dummy,"not");    }
  495.                 strcat(dummy,getlen(adr2));
  496.                 addr(dat1,adr1,reg1);    break;    }
  497.             if ((cmdw&0x0100) || ((reg2==1) && (adr2==3)))
  498.                 break;
  499.             if ((reg2<4) && (adr2==3))
  500.             {    cmdlen=2;    dummy="move";
  501.                 switch(reg2)
  502.                 {    case 0x0:    strcpy(dat1,"sr");
  503.                         addr(dat2,adr1,reg1); break;
  504.                     case 0x2:    cmdlen=1; strcpy(dat2,"ccr");
  505.                         addr(dat1,adr1,reg1); break;
  506.                     case 0x3:    strcpy(dat2,"sr");
  507.                         addr(dat1,adr1,reg1);
  508.                 }
  509.                 break;    }
  510.             if ((cmdw&0x0FF8)==0x840)
  511.             {    dummy="swap";    addr(dat1,0,reg1); break;    }
  512.             if ((cmdw&0x0FA8)==0x880)
  513.             {    strcpy(dummy,"ext");
  514.                 strcat(dummy,getlen(((adr2&0x1)==0)? 1: 2));
  515.                 addr(dat1,0,reg1); break;    }
  516.             if (cmdw==0x4e71)    {    dummy="nop"; break;    }
  517.             if (cmdw==0x4e75)    {    dummy="rts"; break;    }
  518.             if (cmdw==0x4e73)    {    dummy="rte"; break;    }
  519.             if (cmdw==0x4e77)    {    dummy="rtr"; break;    }
  520.             if (cmdw==0x4e76)    {    dummy="trapv";break;    }
  521.             if (cmdw==0x4e70)    {    dummy="reset";break;    }
  522.             if (cmdw==0x4afc)    {    dummy="illegal";break;    }
  523.             if (cmdw==0x4e72)
  524.             {    dummy="stop"; cmdlen=2; addr(dat1,0x7,0x4); break;    }
  525.             if ((cmdw&0x0FF0)==0x0E40)
  526.             {    dummy="trap";
  527.                 sprintf(dat1,"#$%01X",cmdw&0x0F);break;    }
  528.             if ((cmdw&0x0F80)==0x0800)
  529.             {    if (adr2) dummy="pea"; else dummy="nbcd";
  530.                 addr(dat1,adr1,reg1); break;    }
  531.             if ((cmdw&0x0FC0)==0x0AC0)
  532.             {    dummy="tas"; addr(dat1,adr1,reg1); break;    }
  533.             if ((cmdw&0x0F00)==0xA00)
  534.             {    strcpy(dummy,"tst");
  535.                 strcat(dummy,getlen(adr2));
  536.                 addr(dat1,adr1,reg1); break;    }
  537.             if ((cmdw&0x0F80)==0x0E80)
  538.             {    if (cmdw&0x40) dummy="jmp"; else dummy="jsr";
  539.                 addr(dat1,adr1,reg1); break;    }
  540.             if ((cmdw&0x0FF0)==0x0E50)
  541.             {    if (cmdw&0x8)
  542.                 {    dummy="unlk"; addr(dat1,0x1,reg1); break;    }
  543.                 dummy="link"; addr(dat2,0x1,reg1);
  544.                 h2=getword();
  545.                 sprintf(dat1,"#$%04lX",h2); break;    }
  546.             if ((cmdw&0x0FF0)==0x0E60)
  547.             {    dummy="move";
  548.                 if (cmdw&0x8)
  549.                 {    strcpy(dat1,"usp"); addr(dat2,0x1,reg1);
  550.                     break;    }
  551.                 strcpy(dat2,"usp"); addr(dat1,0x1,reg1);
  552.                 break;    }
  553.             if ((cmdw&0x0B80)==0x0880)
  554.             {    strcpy(dummy,"movem");
  555.                 strcat(dummy,getlen((cmdw&0x40)? 2: 1));
  556.                 if (cmdw&0x0400)
  557.                 {    movemreg(dat2,0); addr(dat1,adr1,reg1);
  558.                     break;    }
  559.                 movemreg(dat1,(adr1==0x4)? 1: 0);
  560.                 addr(dat2,adr1,reg1); break;    }
  561.             break;
  562.         case 0x5:
  563.             if ((adr2&0x3)<3)
  564.             {    if (adr2&0x4) strcpy(dummy,"subq");
  565.                     else strcpy(dummy,"addq");
  566.                 strcat(dummy,getlen(adr2&0x3));
  567.                 addr(dat2,adr1,reg1);
  568.                 sprintf(dat1,"#$%02X",qnum(reg2)); break;    }
  569.             if ((cmdw&0x00F8)==0x00C8)
  570.             {    strcpy(dummy,"db"); strcat(dummy,branch(cmdw,1));
  571.                 addr(dat1,0,reg1);
  572.                 h2=getword();
  573.                 h1=PCcount-2+((h2>0x7FFF)? -(0x10000-h2): h2);
  574.                 sprintf(dat2,"$%06lX (rel)",h1); break;    }
  575.             if ((cmdw&0x00C0)==0x00C0)
  576.             {    strcpy(dummy,"s"); strcat(dummy,branch(cmdw,0));
  577.                 addr(dat1,adr1,reg1); break;    }
  578.             break;
  579.         case 0x7:
  580.             if ((cmdw&0x100)==0)
  581.             {    dummy="moveq";    addr(dat2,0,reg2);
  582.                 sprintf(dat1,"#$%02X",cmdw&0xFF);    break;    }
  583.             break;
  584.         case 0x8:
  585.             if ((adr2&0x3)==3)
  586.             {    strcpy(dummy,"divu"); cmdlen=2;
  587.                 if (adr2&0x4) dummy[3]='s';
  588.                 addr(dat2,0,reg2); addr(dat1,adr1,reg1);
  589.                 break;    }
  590.             if ((cmdw&0x01F0)==0x0100)
  591.             {    dummy="sbcd"; addr(dat1,4*adr1,reg1);
  592.                 addr(dat2,4*adr1,reg2); break;    }
  593.             strcpy(dummy,"or");
  594.             strcat(dummy,getlen(adr2&0x3));
  595.             if (adr2&0x4)
  596.             {    addr(dat2,adr1,reg1); addr(dat1,0,reg2);    }
  597.             else
  598.             {    addr(dat1,adr1,reg1); addr(dat2,0,reg2);    }
  599.                 break;
  600.         case 0x9:
  601.             if ((adr2&0x3)==3)
  602.             {    strcpy(dummy,"sub.w"); cmdlen=2;
  603.                 if (adr2&0x4) {    dummy[4]='l'; cmdlen=4;    }
  604.                 addr(dat1,adr1,reg1); addr(dat2,1,reg2);
  605.                 break;    }
  606.             if ((cmdw&0x0130)==0x100)
  607.             {    strcpy(dummy,"subx");
  608.                 strcat(dummy,getlen(adr2&0x3));
  609.                 addr(dat1,4*adr1,reg1);
  610.                 addr(dat2,4*adr1,reg2); break;    }
  611.             strcpy(dummy,"sub");
  612.             strcat(dummy,getlen(adr2&0x3));
  613.             if (adr2&0x4)
  614.             {    addr(dat2,adr1,reg1); addr(dat1,0,reg2);    }
  615.             else
  616.             {    addr(dat1,adr1,reg1); addr(dat2,0,reg2);    }
  617.             break;
  618.         case 0xB:
  619.             if ((adr2&0x3)==0x3)
  620.             {    strcpy(dummy,"cmp.w"); cmdlen=2;
  621.                 if (adr2&0x4) {    dummy[4]='l'; cmdlen=4;    }
  622.                 addr(dat1,adr1,reg1); addr(dat2,1,reg2);
  623.                 break;    }
  624.             if ((adr2&0x4)==0)
  625.             {    strcpy(dummy,"cmp"); strcat(dummy,getlen(adr2));
  626.                 addr(dat1,adr1,reg1); addr(dat2,0,reg2);
  627.                 break;    }
  628.             if (adr1==1)
  629.             {    strcpy(dummy,"cmpm");
  630.                 strcat(dummy,getlen(adr2&0x3));
  631.                 addr(dat1,3,reg1); addr(dat2,3,reg2);
  632.                 break;    }
  633.             strcpy(dummy,"eor");
  634.             strcat(dummy,getlen(adr2&0x3));
  635.             addr(dat1,0,reg2); addr(dat2,adr1,reg1);
  636.             break;
  637.         case 0xC:
  638.             if (((adr2&0x3)==0x3) && (adr1!=1))
  639.             {    strcpy(dummy,"mulu"); cmdlen=2;
  640.                 if (adr2&0x4) dummy[3]='s';
  641.                 addr(dat1,adr1,reg1); addr(dat2,0,reg2);
  642.                 break;    }
  643.             if ((cmdw&0x01F0)==0x100)
  644.             {    dummy="abcd";
  645.                 addr(dat1,4*adr1,reg1);
  646.                 addr(dat2,4*adr1,reg2); break;    }
  647.             if (((cmdw&0x01F0)==0x140) || ((cmdw&0x1F8)==0x188))
  648.             {    dummy="exg";
  649.                 if (adr1==0)
  650.                 {    addr(dat2,0,reg1); addr(dat1,0,reg2);
  651.                     break;    }
  652.                 addr(dat1,2,reg1);
  653.                 if (adr2&0x1) addr(dat1,1,reg2);
  654.                     else addr(dat1,0,reg2);
  655.                 break;    }
  656.             strcpy(dummy,"and"); strcat(dummy,getlen(adr2&0x3));
  657.             if (adr2&0x4)
  658.             {    addr(dat1,0,reg2); addr(dat2,adr1,reg1);    }
  659.             else
  660.             {    addr(dat2,0,reg2); addr(dat1,adr1,reg1);    }
  661.             break;
  662.         case 0xD:
  663.             if ((adr2&0x3)==0x3)
  664.             {    strcpy(dummy,"add.w"); cmdlen=2;
  665.                 if (adr2&0x4)    {    dummy[4]='l'; cmdlen=4;    }
  666.                 addr(dat1,adr1,reg1); addr(dat2,1,reg2);
  667.                 break;    }
  668.             if ((adr2&0x4) && (adr1<2))
  669.             {    strcpy(dummy,"addx");
  670.                 strcat(dummy,getlen(adr2&0x3));
  671.                 addr(dat1,4*adr1,reg1);
  672.                 addr(dat2,4*adr1,reg2); break;    }
  673.             strcpy(dummy,"add"); strcat(dummy,getlen(adr2&0x3));
  674.             if (adr2&0x4)
  675.             {    addr(dat1,0,reg2); addr(dat2,adr1,reg1);    }
  676.             else
  677.             {    addr(dat2,0,reg2); addr(dat1,adr1,reg1);    }
  678.             break;
  679.         case 0xE:
  680.             if ((adr2&0x3)<3)
  681.             {    switch(adr1&0x3)
  682.                 {    case 0x0: strcpy(dummy,"as"); break;
  683.                     case 0x1: strcpy(dummy,"ls"); break;
  684.                     case 0x2: strcpy(dummy,"rox");break;
  685.                     case 0x3: strcpy(dummy,"ro");        }
  686.                 if (adr2&0x4) strcat(dummy,"l");
  687.                     else strcat(dummy,"r");
  688.                 strcat(dummy,getlen(adr2&0x3));
  689.                 if (adr1&0x4)    addr(dat1,0,reg2);
  690.                     else sprintf(dat1,"#$%02X",qnum(reg2));
  691.                 addr(dat2,0,reg1); break;    }
  692.             h2=0;
  693.             switch((cmdw&0x0E00)>>9)
  694.             {    case 0x0: strcpy(dummy,"as"); break;
  695.                 case 0x1: strcpy(dummy,"ls"); break;
  696.                 case 0x2: strcpy(dummy,"rox");break;
  697.                 case 0x3: strcpy(dummy,"ro"); break;
  698.                 default:  h2=1;    }
  699.             if (h2) break;
  700.             if (adr2&0x4) strcat(dummy,"l");
  701.                 else strcat(dummy,"r"); cmdlen=1;
  702.             addr(dat1,adr1,reg1); break;    }
  703.     putstr("   ");
  704.     if (dummy[0]==0) putstr(nokn); else putstr(dummy);
  705.     if (dat1[0])
  706.     {    putstr("   "); putstr(dat1);
  707.         if (dat2[0])
  708.         {    putchar(','); putstr(dat2);    }}
  709.     return;
  710. }
  711. unsigned int getword()
  712. {    PCcount+=2L;
  713.     return (((*(curbyte++))<<8)+(*(curbyte++)));
  714. }
  715. char *branch(unsigned int cmd,int flag)
  716. {    int t;
  717.     t=(cmd&0x0F00)>>8;
  718.     switch(t)
  719.     {    case 0:
  720.             if (flag&0x1) return "ra"; else return "t";
  721.         case 0x1:
  722.             if (flag&0x2) return "sr"; else return "f";
  723.         case 0x2: return "hi";
  724.         case 0x3: return "ls";
  725.         case 0x4: return "cc";
  726.         case 0x5: return "cs";
  727.         case 0x6: return "ne";
  728.         case 0x7: return "eq";
  729.         case 0x8: return "vc";
  730.         case 0x9: return "vs";
  731.         case 0xA: return "pl";
  732.         case 0xB: return "mi";
  733.         case 0xC: return "ge";
  734.         case 0xD: return "lt";
  735.         case 0xE: return "gt";
  736.         case 0xF: return "le";
  737.     }
  738.     return "??";
  739. }
  740. void addr(char *buf,unsigned int mode,unsigned int reg)
  741. {    switch(mode)
  742.     {    case 0x0:    /* Dx */
  743.             buf[0]='d'; buf[1]='0'+reg; buf[2]=0;
  744.             return;
  745.         case 0x1:    /* Ax */
  746.             buf[0]='a'; buf[1]='0'+reg;    buf[2]=0;
  747.             return;
  748.         case 0x2:    /* (Ax) */
  749.             buf[1]='a'; buf[2]='0'+reg;
  750.             buf[0]='('; buf[3]=')'; buf[4]=0;
  751.             return;
  752.         case 0x3:    /* (Ax)+ */
  753.             buf[0]='('; buf[1]='a'; buf[2]='0'+reg;
  754.             buf[3]=')'; buf[4]='+'; buf[5]=0;
  755.             return;
  756.         case 0x4:    /* -(Ax) */
  757.             buf[0]='-'; buf[1]='('; buf[2]='a';
  758.             buf[3]='0'+reg; buf[4]=')'; buf[5]=0;
  759.             return;
  760.         case 0x5:    /* $xxxx(Ax) */
  761.             h2=getword(); sprintf(buf,"$%04lX",h2);
  762.             buf[5]='('; buf[6]='a'; buf[7]='0'+reg;
  763.             buf[8]=')'; buf[9]=0;
  764.             return; 
  765.         case 0x6:    /* $xx(Ax,A/Dy.?) */
  766.             h2=getword();
  767.             sprintf(buf,"$%02lX",h2&0xFF);
  768.             buf[3]='('; buf[4]='a'; buf[5]='0'+reg; buf[6]=',';
  769.             buf[7]=((h2&0x8000)? 'a': 'd');
  770.             buf[8]='0'+((h2&0x7000)>>12); buf[9]='.';
  771.             buf[10]=((h2&0x0800)? 'l': 'w');
  772.             buf[11]=')'; buf[12]=0;
  773.             return;
  774.         case 0x7:    /* Der Rest */
  775.             switch(reg)
  776.             {    case 0x0:    /* $xxxx */
  777.                     h2=getword();
  778.                     sprintf(buf,"$%04lX",h2);
  779.                     return;
  780.                 case 0x1:    /* $xxxxxxxx */
  781.                     h2=getword()&0xFF;
  782.                     sprintf(buf,"$%02lX",h2);
  783.                     h2=getword();
  784.                     sprintf(&buf[3],"%04lX",h2);
  785.                     return;
  786.                 case 0x2:    /* $xxxx(PC) */
  787.                     h2=getword();
  788.                     h1=PCcount-2+((h2>0x7FFF)? -(0x10000-h2): h2);
  789.                     sprintf(buf,"$%06lX(pc)",h1&0xFFFFFF);
  790.                     return;
  791.                 case 0x3:    /* $xx(PC,A/Dx.?) */
  792.                     h2=getword();
  793.                     sprintf(buf,"$%02lX(pc,",h2&0xFF);
  794.                     buf[7]=((h2&0x8000)? 'a': 'd');
  795.                     buf[8]='0'+((h2&0x7000)>>12); buf[9]='.';
  796.                     buf[10]=((h2&0x0800)? 'l': 'w');
  797.                     buf[11]=')'; buf[12]=0;
  798.                     return;
  799.                 case 0x4:    /* #$xx... */
  800.                     switch(cmdlen)
  801.                     {    case 1:    /* Byte */
  802.                             h2=getword();
  803.                             sprintf(buf,"#$%02lX",h2&0xFF);
  804.                             return;
  805.                         case 2:    /* Word */
  806.                             h2=getword();
  807.                             sprintf(buf,"#$%04lX",h2);
  808.                             return;
  809.                         case 4:    /* Long */
  810.                             h2=getword();
  811.                             sprintf(buf,"#$%04lX",h2);
  812.                             h2=getword();
  813.                             sprintf(&buf[6],"%04lX",h2);
  814.                             return;
  815.                     }
  816.                 default:    strcpy(buf,"???");
  817.                             return;
  818.             }
  819.         default: strcpy(buf,"???");
  820.     }
  821.     return;
  822. }
  823. char *getlen(int binleng)
  824. {    switch(binleng)
  825.     {    case 0x0: cmdlen=1; return ".b";
  826.         case 0x1: cmdlen=2; return ".w";
  827.         case 0x2: cmdlen=4; return ".l";
  828.     }
  829.     cmdlen=0; return ".?";
  830. }
  831. void movemreg(char *dat,int flag)
  832. {    char bufz[1];
  833.     unsigned int i,j,k,l;
  834.     h2=getword();
  835.     if (flag)
  836.     {    h1=0; k=1;
  837.         for (i=0; i<16;)
  838.             h1=(h1 | ((h2&(1<<(i++)))? (1<<(16-i)):0 ));
  839.         h2=h1;    }
  840.     k=(h2&0xFF);    l=(h2&0xFF00);
  841.     bufz[1]=0;
  842.     if (k)
  843.     {    strcat(dat,"d");
  844.         for (i=0; i<8; )
  845.         {    if (k&(1<<(i++)))
  846.             {    bufz[0]='0'+i-1; strcat(dat,bufz);    }}
  847.         if (l) strcat(dat,"/");    }
  848.     if (l)
  849.     {    strcat(dat,"a");
  850.         for (i=0; i<8; )
  851.         {    if (l&(0x100<<(i++)))
  852.             {    bufz[0]='0'+i-1; strcat(dat,bufz);    }}}
  853.     return;
  854. }
  855. unsigned int qnum(unsigned int z)
  856. {    if (z==0) return (8);
  857.     return (z);
  858. }
  859. /* o.k., das war's */